////////////////////////////////////////////////////////
//	File:		OptionsState.cpp
//	Class:		SGP
//	Updated:	3/6/2012
//	Author:		Roc Myers
//	Purpose:	To contain all Options Menu related code
////////////////////////////////////////////////////////
#include "OptionsState.h"
#include "Game.h"
#include "MainMenuState.h"
#include "tinyxml\tinyxml.h"
#include "SGD Wrappers\CSGD_XAudio2.h"
#include "SGD Wrappers\CSGD_TextureManager.h"
#include "SGD Wrappers\CSGD_Direct3D.h"
#include "SGD Wrappers\CSGD_DirectInput.h"
OptionsState* OptionsState::pInstance = nullptr;

OptionsState::OptionsState(void)
{
	BGMID			= -1;
	SFXID			= -1;
	CursorID		= -1;
	BackgroundID	= -1;
	FontID			= -1;
	declineID		= -1;
	acceptID		= -1;
	errorID			= -1;
	moveID			= -1;
	musicTimer		= 0.0f;
	isWindowed		= false;
}


OptionsState::~OptionsState(void)
{
}

OptionsState* OptionsState::GetInstance(void)
{
	if(pInstance == nullptr)
		pInstance = new OptionsState();

	return pInstance;
}

void OptionsState::DeleteInstance()
{
	if(pInstance != nullptr)
	{
		delete pInstance;
		pInstance = nullptr;
	}
}

void OptionsState::Enter(void)
{
	// Load Resources
	SFXID = CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/soundFX/FX/Cardboard_Swish.wav"));
	BGMID	= CSGD_XAudio2::GetInstance()->MusicLoadSong(_T("resource/Team Making.xwm"));
	CursorID = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/SGD_MenuCursor.png"),D3DCOLOR_XRGB(0,0,0));
	FontID = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/LARPFont.png"));
	BackgroundID = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/optionsmenu.png"));
	Selection = 0;
	File = 0;
	Delete = false;
	Font.Initialize(FontID,"LARPFont.fnt");

	// Set up sound
	sfxVol	= Game::GetInstance()->SfxVol;
	bgmVol	= Game::GetInstance()->BgmVol;
	pan		= Game::GetInstance()->Pan;

	// Get fullscreen
	isWindowed = Game::GetInstance()->Fullscreen;
	
	CSGD_XAudio2::GetInstance()->MusicSetSongPan(BGMID,pan);
	CSGD_XAudio2::GetInstance()->MusicPlaySong(BGMID,true);

	declineID	= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/soundFX/GUI/GUI_InGame_Decline.wav"));
	acceptID	= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/soundFX/GUI/GUI_InGame_Accept.wav"));
	errorID		= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/soundFX/GUI/GUI_InGame_Error.wav"));
	moveID		= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/soundFX/GUI/GUI_Main_Move.wav"));

	arcadeEnter = false;
	arcadeEscape = false;
	arcadeUp = false;
	arcadeDown = false;
	arcadeLeft = false;
	arcadeRight = false;
	arcadeBackspace = false;
	arcadeShift = false;
	arcadePlus = false;
	arcadeMinus = false;
	arcadeP = false;

}

bool OptionsState::Input(void)
{
	ArcadeInput();


	if(!Delete)
	{
		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_ESCAPE)||arcadeEscape)
			Selection = 5;

		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP)||arcadeUp)
		{
			CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);

			if(Selection > 0)
				Selection -= 1;
			else
				Selection = 5;
		}

		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN)||arcadeDown)
		{
			CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);

			if(Selection < 5)
				Selection += 1;
			else
				Selection = 0;
		}
		switch(Selection)
		{
		case 0:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RIGHT)||arcadeRight)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(sfxVol < 1.0f)
					CSGD_XAudio2::GetInstance()->SFXSetMasterVolume((float)(sfxVol += 0.01f));
				CSGD_XAudio2::GetInstance()->SFXPlaySound(SFXID);
			}
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_LEFT)||arcadeLeft)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(sfxVol > 0.0f)
					CSGD_XAudio2::GetInstance()->SFXSetMasterVolume((float)(sfxVol -= 0.01f));
				CSGD_XAudio2::GetInstance()->SFXPlaySound(SFXID);
			}
			break;
			
		case 1:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RIGHT)||arcadeRight)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(bgmVol < 1.0f)
					CSGD_XAudio2::GetInstance()->MusicSetMasterVolume((float)(bgmVol += 0.01f));
			}
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_LEFT)||arcadeLeft)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(bgmVol > 0.0f)
					CSGD_XAudio2::GetInstance()->MusicSetMasterVolume((float)(bgmVol -= 0.01f));
			}
			break;

		case 2:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RIGHT)||arcadeRight)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(pan < 0.90f)
					CSGD_XAudio2::GetInstance()->MusicSetSongPan(BGMID,(float)(pan += 0.20f));
			}
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_LEFT)||arcadeLeft)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
				if(pan > -0.90f)
					CSGD_XAudio2::GetInstance()->MusicSetSongPan(BGMID,(float)(pan -= 0.20f));
			}
			break;

		case 3:
			{
				if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
				{
					Delete = true;
					break;
				}
			}

		case 4:
			{
				if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_LEFT)||arcadeLeft ||  CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RIGHT)||arcadeRight)
				{
					CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);
					isWindowed = !isWindowed;
					CSGD_Direct3D::GetInstance()->ChangeDisplayParam(Game::GetInstance()->GetWinWidth(), Game::GetInstance()->GetWinHeight(), isWindowed);
					Game::GetInstance()->Fullscreen = isWindowed;
				}
			}
			break;

			case 5:
			if(!CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT) && !CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT))
				if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
					Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
			break;
		};
	}
	else if(Delete)
	{
		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_ESCAPE)||arcadeEscape)
			File = 3;

		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP)||arcadeUp)
		{
			CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);

			if(File > 0)
				File -= 1;
			else
				File = 3;
		}

		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN)||arcadeDown)
		{
			CSGD_XAudio2::GetInstance()->SFXPlaySound(moveID);

			if(File < 3)
				File += 1;
			else
				File = 0;
		}
		switch(File)
		{
		case 0:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(acceptID);
				ClearFile(1);
				break;
			}

		case 1:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(acceptID);
				ClearFile(2);
				break;
			}

		case 2:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(acceptID);
				ClearFile(3);
				break;
			}

		case 3:
			if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN)||arcadeEnter)
			{
				CSGD_XAudio2::GetInstance()->SFXPlaySound(declineID);
				Delete = false;
				File = 0;
				break;
			}
		};
	}
	return true;
}

void OptionsState::Update(float fElapsedTime)
{
	musicTimer += fElapsedTime;

	if(musicTimer >= 54.0f)
	{
		CSGD_XAudio2::GetInstance()->MusicStopSong(BGMID);
		CSGD_XAudio2::GetInstance()->MusicPlaySong(BGMID);
		musicTimer = 0.0f;
	}
}

void OptionsState::Render(void)
{
	char buffer[50];
	CSGD_TextureManager::GetInstance()->Draw(BackgroundID,0,-138,0.8f,0.72f);

	if(!Delete)
	{
		Font.Print("Options", 250, 35, 3.0f);
		Font.Print("SFX Volume", 90, 175, 2.0f);
		Font.Print("BGM Volume", 85, 235, 2.0f);
		Font.Print("Pan", 90, 295, 2.0f);
		Font.Print("Delete Save", 90, 355, 2.0f);
		Font.Print("Full Screen", 90, 415, 2.0f);
		Font.Print("Back", 90, 475, 2.0f);

		if(isWindowed)
			Font.Print("OFF", 510, 415, 2.0f);
		else
			Font.Print("ON", 510, 415, 2.0f);

		int volume;
		volume = (int)(floor(sfxVol * 100));
		if(volume < 0)
			volume = 0;
		sprintf_s(buffer, "(%d)", volume);
		Font.Print(buffer, 510, 175, 2.0f);

		volume = (int)(floor(bgmVol * 100));
		if(volume < 0)
			volume = 0;
		sprintf_s(buffer, "(%d)", volume);
		Font.Print(buffer, 510, 235, 2.0f);

		if(pan < 0)
		{
			sprintf_s(buffer, "L(%d)", (int)((50+((pan * -100)/2))));
			Font.Print(buffer, 477, 295, 2.0f);
		}
		else if(pan == 0)
			Font.Print("L(50)", 477, 295, 2.0f);
		else
		{
			sprintf_s(buffer, "L(%d)", (int)((50-((pan * 100)/2))));
			Font.Print(buffer, 477, 295, 2.0f);
		}

		if(pan > 0)
		{
			sprintf_s(buffer, "R(%d)", (int)((50+((pan * 100)/2))));
			Font.Print(buffer, 580, 295, 2.0f);
		}
		else if(pan == 0)
			Font.Print("R(50)", 580, 295, 2.0f);
		else
		{
			sprintf_s(buffer, "R(%d)", (int)((50-((pan * -100)/2))));
			Font.Print(buffer, 580, 295, 2.0f);
		}

		switch(Selection)
		{
		case 0:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 205);
			break;
		
		case 1:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 265);
			break;

		case 2:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 325);
			break;

		case 3:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 385);
			break;

		case 4:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 445);
			break;

		case 5:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 60, 505);
			break;
		};
	}
	else if(Delete)
	{
		Font.Print("Save Deletion", 160, 35, 3.0f);
		Font.Print("Slot 1", 300, 175, 2.0f);
		Font.Print("Slot 2", 295, 235, 2.0f);
		Font.Print("Slot 3", 300, 295, 2.0f);
		Font.Print("Done", 300, 355, 2.0f);

		switch(File)
		{
		case 0:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 270, 205);
			break;
		
		case 1:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 270, 265);
			break;

		case 2:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 270, 325);
			break;

		case 3:
			CSGD_TextureManager::GetInstance()->Draw(CursorID, 270, 385);
			break;
		};
	}
}

void OptionsState::Exit(void)
{
	SaveSettings("settings.xml");
	Game::GetInstance()->SfxVol	= sfxVol;
	Game::GetInstance()->BgmVol	= bgmVol;
	Game::GetInstance()->Pan	= pan;

	CSGD_XAudio2* XA = CSGD_XAudio2::GetInstance();

	XA->MusicStopSong(BGMID);
	
	if(moveID != -1)
	{
		XA->SFXStopSound(moveID);
		XA->SFXUnloadSound(moveID);
		moveID = -1;
	}
	
	if(acceptID != -1)
	{
		XA->SFXStopSound(acceptID);
		XA->SFXUnloadSound(acceptID);
		acceptID = -1;
	}
	
	if(declineID != -1)
	{
		XA->SFXStopSound(declineID);
		XA->SFXUnloadSound(declineID);
		declineID = -1;
	}
	
	if(errorID != -1)
	{
		XA->SFXStopSound(errorID);
		XA->SFXUnloadSound(errorID);
		errorID = -1;
	}
	
	if(SFXID != -1)
	{
		XA->SFXUnloadSound(SFXID);
		SFXID	= -1;
	}

	if(BGMID != -1)
	{
		XA->MusicUnloadSong(BGMID);
		BGMID = -1;
	}

	if(CursorID != -1)
	{
		CSGD_TextureManager::GetInstance()->UnloadTexture(CursorID);
		CursorID = -1;
	}

	if(BackgroundID != -1)
	{
		CSGD_TextureManager::GetInstance()->UnloadTexture(BackgroundID);
		BackgroundID = -1;
	}

	if(FontID != -1)
	{
		CSGD_TextureManager::GetInstance()->UnloadTexture(FontID);
		FontID = -1;
	}

	DeleteInstance();
}

void OptionsState::SaveSettings(const char* szFileName)
{
	// Create the TinyXML document
	TiXmlDocument doc;

	// Create the TinyXML Declaration (version)
	TiXmlDeclaration* pDec = new TiXmlDeclaration( "1.0", "utf-8", "" );

	// Write the declaration to the document
	doc.LinkEndChild( pDec );

	TiXmlElement* pRoot = new TiXmlElement("sound");
	doc.LinkEndChild(pRoot);

	TiXmlElement* pSettings = new TiXmlElement("settings");
	pSettings->SetDoubleAttribute("SfxVol", sfxVol);
	pSettings->SetDoubleAttribute("BgmVol", bgmVol);
	pSettings->SetDoubleAttribute("Pan", pan);
	pRoot->LinkEndChild(pSettings);

	// Save the XML Document to the file
	doc.SaveFile( szFileName );
}

bool OptionsState::ClearFile(int fileNumber)
{
	// Create the TinyXML document
	TiXmlDocument doc;

	// Create the TinyXML Declaration (version)
	TiXmlDeclaration* pDec = new TiXmlDeclaration( "1.0", "utf-8", "" );

	// Write the declaration to the document
	doc.LinkEndChild( pDec );

	// Save the XML Document to the correct "slot"
	switch(fileNumber)
	{
	case 1:
		{
			const char* name = "SaveSlot1.xml";
			doc.SaveFile(name);
			break;
		}

	case 2:
		{
			const char* name = "SaveSlot2.xml";
			doc.SaveFile(name);
			break;
		}

	case 3:
		{
			const char* name = "SaveSlot3.xml";
			doc.SaveFile(name);
			break;
		}
	};

	return true;
}

void OptionsState::ArcadeInput()
{
	arcadeEnter = false;
	arcadeEscape = false;
	arcadeUp = false;
	arcadeDown = false;
	arcadeLeft = false;
	arcadeRight = false;
	arcadeBackspace = false;
	arcadeShift = false;
	arcadePlus = false;
	arcadeMinus = false;
	arcadeP = false;

	CSGD_DirectInput * di = CSGD_DirectInput::GetInstance();

	if(di->JoystickGetLStickDirPressed(DIR_UP,0))
	{
		arcadeUp = true;
	}

	if(di->JoystickGetLStickDirPressed(DIR_DOWN,0))
	{
		arcadeDown = true;
	}

	if(di->JoystickGetLStickDirPressed(DIR_LEFT,0))
	{
		arcadeLeft = true;
	}

	if(di->JoystickGetLStickDirPressed(DIR_RIGHT,0))
	{
		arcadeRight = true;
	}

	if(di->JoystickButtonPressed(0,0))
	{
		arcadeEnter = true;
	}

	if(di->JoystickButtonPressed(1,0))
	{
		arcadeBackspace = true;
	}

	if(di->JoystickButtonPressed(2,0))
	{
		arcadeP = true;
	}

	if(di->JoystickButtonPressed(3,0))
	{
		arcadeShift = true;
	}

	if(di->JoystickButtonPressed(4,0))
	{
		arcadePlus = true;
	}

	if(di->JoystickButtonPressed(5,0))
	{
		arcadeMinus = true;
	}

	if(di->JoystickButtonPressed(6,0))
	{
		arcadeEscape = true;
	}
}